using System;

namespace test {
    class MainClass {
        public static void Main(string[] args) {
            FuzzyLogic logic = new FuzzyLogic();
            TrapMf mf = new TrapMf(3, 5, 7, 9);
            Console.WriteLine("eval = " + mf.evalAt(6.1f));
            new RuleReader("../../test.txt", logic);

            float damage_input = 13;
            float health_input = 65;
            float playerpos_input = 12;

            float damage_l_input = 0;
            float damage_m_input = 0;
            float damage_h_input = 0;

            float health_vl_input = 0;
            float health_l_input = 0;
            float health_m_input = 0;
            float health_h_input = 0;
            float health_vh_input = 0;

            float playerpos_vc_input = 0;
            float playerpos_c_input = 0;
            float playerpos_a_input = 0;
            float playerpos_f_input = 0;
            float playerpos_vf_input = 0;

            float INIF = 1000;

            TrapMf playerpos_vc = new TrapMf(-INIF, -INIF, 10, 13);
            TrapMf playerpos_c = new TrapMf(10, 13, 17, 18);
            TrapMf playerpos_m = new TrapMf(17, 18, 22, 23);
            TrapMf playerpos_f = new TrapMf(22, 23, 27, 28);
            TrapMf playerpos_vf = new TrapMf(28, 29, INIF, INIF);

            TrapMf health_vl = new TrapMf(-INIF, -INIF, 15, 20);
            TrapMf health_l = new TrapMf(15, 20, 30, 40);
            TrapMf health_a = new TrapMf(30, 40, 60, 70);
            TrapMf health_h = new TrapMf(60, 70, 80, 85);
            TrapMf health_vh = new TrapMf(80, 85, INIF, INIF);

            TrapMf damage_l = new TrapMf(-INIF, -INIF, 5, 7);
            TrapMf damage_m = new TrapMf(5, 7, 12, 15);
            TrapMf damage_h = new TrapMf(12, 17, INIF, INIF);

            damage_l_input = damage_l.evalAt(damage_input);
            damage_m_input = damage_m.evalAt(damage_input);
            damage_h_input = damage_h.evalAt(damage_input);

            health_vl_input = health_vl.evalAt(health_input);
            health_l_input = health_l.evalAt(health_input);
            health_m_input = health_a.evalAt(health_input);
            health_h_input = health_h.evalAt(health_input);
            health_vh_input = health_vh.evalAt(health_input);

            playerpos_vc_input = playerpos_vc.evalAt(playerpos_input);
            playerpos_c_input = playerpos_c.evalAt(playerpos_input);
            playerpos_a_input = playerpos_m.evalAt(playerpos_input);
            playerpos_f_input = playerpos_f.evalAt(playerpos_input);
            playerpos_vf_input = playerpos_vf.evalAt(playerpos_input);

            Console.WriteLine("health_vl_input is " + health_vl_input);
            Console.WriteLine("health_l_input is " + health_l_input);
            Console.WriteLine("health_m_input is " + health_m_input);
            Console.WriteLine("health_h_input is " + health_h_input);
            Console.WriteLine("health_vh_input is " + health_vh_input);

            Console.WriteLine("playerpos_vc_input is " + playerpos_vc_input);
            Console.WriteLine("playerpos_c_input is " + playerpos_c_input);
            Console.WriteLine("playerpos_a_input is " + playerpos_a_input);
            Console.WriteLine("playerpos_f_input is " + playerpos_f_input);
            Console.WriteLine("playerpos_vf_input is " + playerpos_vf_input);

            Console.WriteLine("damage_l_input is " + damage_l_input);
            Console.WriteLine("damage_m_input is " + damage_m_input);
            Console.WriteLine("damage_h_input is " + damage_h_input);

            logic.addInputs(
                playerpos_vc_input, playerpos_c_input, playerpos_a_input, playerpos_f_input, playerpos_vf_input,
                health_vl_input, health_l_input, health_m_input, health_h_input, health_vh_input,
                damage_l_input, damage_m_input, damage_h_input
                );

            logic.evalutate();
            logic.defuzzify();

            while (true) ;
        }
    }

    class TrapMf {
        private float botLeft;
        private float topLeft;
        private float topRight;
        private float botRight;

        private float leftWidth;
        private float rightWidth;

        public TrapMf(params float[] arr) {
            botLeft = arr[0];
            topLeft = arr[1];
            topRight = arr[2];
            botRight = arr[3];

            leftWidth = topLeft - botLeft;
            rightWidth = botRight - topRight;
        }

        public float evalAt(float val) {
            if (val >= topLeft && val <= topRight) {
                return 1.0f;
            } else if (val <= botLeft || val >= botRight) {
                return 0.0f;
            } else if (val > botLeft && val < topLeft) {
                return (topLeft - val) / leftWidth;
            } else if (val > topRight && val < botRight) {
                return (botRight - val) / rightWidth;
            }
            return -1.0f;
        }
    }
}